import { AudioManager } from './AudioManager';
import { 
  SoundEffectType, 
  BackgroundMusicType, 
  AUDIO_THEMES,
  getSoundEffectConfig,
  getBackgroundMusicConfig,
  getAudioThemeConfig,
  type AudioThemeConfig
} from './AudioAssets';

/**
 * 游戏音频系统
 * 负责管理游戏中的所有音频播放，包括音效和背景音乐
 * 提供高级的音频控制接口，支持主题切换和动态音量调节
 * @class
 */
export class GameAudioSystem {
  private audioManager: AudioManager;
  private currentTheme: string = 'gameNormal';
  private currentBackgroundMusic: BackgroundMusicType | null = null;
  private isInitialized: boolean = false;
  private loadingPromises: Map<string, Promise<void>> = new Map();

  /**
   * 创建游戏音频系统实例
   * @param audioManager - 音频管理器实例
   */
  constructor(audioManager: AudioManager) {
    this.audioManager = audioManager;
  }

  /**
   * 初始化游戏音频系统
   * 初始化AudioManager并预加载基础音效
   * @returns Promise<void>
   * @throws 当音频系统初始化失败时抛出错误
   */
  async initialize(): Promise<void> {
    try {
      // 初始化AudioManager
      if (!this.audioManager.isReady()) {
        await this.audioManager.initialize();
      }

      // 预加载基础音效（跳跃、收集等常用音效）
      await this.preloadEssentialSounds();

      this.isInitialized = true;
      console.log('游戏音频系统初始化成功');
    } catch (error) {
      console.error('游戏音频系统初始化失败:', error);
      throw new Error('音频系统初始化失败');
    }
  }

  /**
   * 预加载基础音效
   * 加载游戏中最常用的音效，提高响应速度
   * @private
   */
  private async preloadEssentialSounds(): Promise<void> {
    const essentialSounds = [
      SoundEffectType.JUMP,
      SoundEffectType.SLIDE,
      SoundEffectType.COLLECT_COIN,
      SoundEffectType.COLLISION,
      SoundEffectType.BUTTON_CLICK
    ];

    const loadPromises = essentialSounds.map(soundType => 
      this.loadSoundEffect(soundType)
    );

    await Promise.all(loadPromises);
    console.log('基础音效预加载完成');
  }

  /**
   * 加载音效
   * @param soundType - 音效类型
   * @returns Promise<void>
   */
  async loadSoundEffect(soundType: SoundEffectType): Promise<void> {
    const soundKey = `sound_${soundType}`;
    
    // 避免重复加载
    if (this.loadingPromises.has(soundKey)) {
      return this.loadingPromises.get(soundKey)!;
    }

    const config = getSoundEffectConfig(soundType);
    const loadPromise = this.audioManager.loadSound(soundKey, config.url);
    
    this.loadingPromises.set(soundKey, loadPromise);
    
    try {
      await loadPromise;
      console.log(`音效 ${soundType} 加载成功`);
    } catch (error) {
      console.warn(`音效 ${soundType} 加载失败:`, error);
      this.loadingPromises.delete(soundKey);
      throw error;
    }
  }

  /**
   * 加载背景音乐
   * @param musicType - 背景音乐类型
   * @returns Promise<void>
   */
  async loadBackgroundMusic(musicType: BackgroundMusicType): Promise<void> {
    const musicKey = `music_${musicType}`;
    
    // 避免重复加载
    if (this.loadingPromises.has(musicKey)) {
      return this.loadingPromises.get(musicKey)!;
    }

    const config = getBackgroundMusicConfig(musicType);
    const loadPromise = this.audioManager.loadBackgroundMusic(config.url);
    
    this.loadingPromises.set(musicKey, loadPromise);
    
    try {
      await loadPromise;
      console.log(`背景音乐 ${musicType} 加载成功`);
    } catch (error) {
      console.warn(`背景音乐 ${musicType} 加载失败:`, error);
      this.loadingPromises.delete(musicKey);
      throw error;
    }
  }

  /**
   * 播放音效
   * @param soundType - 音效类型
   * @param volumeMultiplier - 音量倍数 (0-1)，可选参数
   * @returns boolean - 是否成功播放
   * @example
   * gameAudioSystem.playSoundEffect(SoundEffectType.JUMP);
   */
  playSoundEffect(soundType: SoundEffectType, volumeMultiplier: number = 1.0): boolean {
    if (!this.isInitialized) {
      console.warn('音频系统未初始化，无法播放音效');
      return false;
    }

    const soundKey = `sound_${soundType}`;
    const themeConfig = getAudioThemeConfig(this.currentTheme);
    const config = getSoundEffectConfig(soundType, themeConfig?.soundOverrides);
    const finalVolume = config.volume * volumeMultiplier;

    return this.audioManager.playSound(soundKey, finalVolume);
  }

  /**
   * 播放背景音乐
   * @param musicType - 背景音乐类型
   * @param fadeIn - 是否淡入播放，默认为false
   * @returns Promise<boolean> - 是否成功播放
   * @example
   * await gameAudioSystem.playBackgroundMusic(BackgroundMusicType.GAME_NORMAL);
   */
  async playBackgroundMusic(musicType: BackgroundMusicType, _fadeIn: boolean = false): Promise<boolean> {
    if (!this.isInitialized) {
      console.warn('音频系统未初始化，无法播放背景音乐');
      return false;
    }

    // 如果已经在播放相同的音乐，则不重复播放
    if (this.currentBackgroundMusic === musicType && this.audioManager.isMusicPlaying()) {
      return true;
    }

    try {
      // 确保背景音乐已加载
      await this.loadBackgroundMusic(musicType);

      // 停止当前播放的音乐
      this.stopBackgroundMusic();

      const config = getBackgroundMusicConfig(musicType);
      const success = this.audioManager.playMusic(config.loop);

      if (success) {
        this.currentBackgroundMusic = musicType;
        console.log(`开始播放背景音乐: ${musicType}`);
      }

      return success;
    } catch (error) {
      console.error(`播放背景音乐失败: ${musicType}`, error);
      return false;
    }
  }

  /**
   * 停止背景音乐
   * @example
   * gameAudioSystem.stopBackgroundMusic();
   */
  stopBackgroundMusic(): void {
    this.audioManager.stopMusic();
    this.currentBackgroundMusic = null;
    console.log('背景音乐已停止');
  }

  /**
   * 切换音频主题
   * @param themeName - 主题名称
   * @returns Promise<boolean> - 是否成功切换
   * @example
   * await gameAudioSystem.switchTheme('bossBattle');
   */
  async switchTheme(themeName: string): Promise<boolean> {
    const themeConfig = getAudioThemeConfig(themeName);
    if (!themeConfig) {
      console.warn(`未找到音频主题: ${themeName}`);
      return false;
    }

    try {
      // 先尝试切换背景音乐
      const musicResult = await this.playBackgroundMusic(themeConfig.backgroundMusic);
      if (!musicResult) {
        console.error(`切换音频主题失败: ${themeName} - 背景音乐播放失败`);
        return false;
      }
      
      // 只有背景音乐成功播放后才更新主题
      this.currentTheme = themeName;
      
      console.log(`音频主题已切换到: ${themeName}`);
      return true;
    } catch (error) {
      console.error(`切换音频主题失败: ${themeName}`, error);
      return false;
    }
  }

  /**
   * 设置主音量
   * @param volume - 音量大小 (0-1)
   * @example
   * gameAudioSystem.setMasterVolume(0.8);
   */
  setMasterVolume(volume: number): void {
    this.audioManager.setMasterVolume(volume);
  }

  /**
   * 设置背景音乐音量
   * @param volume - 音量大小 (0-1)
   * @example
   * gameAudioSystem.setMusicVolume(0.6);
   */
  setMusicVolume(volume: number): void {
    this.audioManager.setMusicVolume(volume);
  }

  /**
   * 设置音效音量
   * @param volume - 音量大小 (0-1)
   * @example
   * gameAudioSystem.setSfxVolume(0.9);
   */
  setSfxVolume(volume: number): void {
    this.audioManager.setSfxVolume(volume);
  }

  /**
   * 获取当前主音量
   * @returns 当前主音量值 (0-1)
   */
  getMasterVolume(): number {
    return this.audioManager.getMasterVolume();
  }

  /**
   * 获取当前背景音乐音量
   * @returns 当前背景音乐音量值 (0-1)
   */
  getMusicVolume(): number {
    return this.audioManager.getMusicVolume();
  }

  /**
   * 获取当前音效音量
   * @returns 当前音效音量值 (0-1)
   */
  getSfxVolume(): number {
    return this.audioManager.getSfxVolume();
  }

  /**
   * 获取当前音频主题
   * @returns 当前主题名称
   */
  getCurrentTheme(): string {
    return this.currentTheme;
  }

  /**
   * 获取当前播放的背景音乐类型
   * @returns 当前背景音乐类型，如果没有播放则返回null
   */
  getCurrentBackgroundMusic(): BackgroundMusicType | null {
    return this.currentBackgroundMusic;
  }

  /**
   * 检查音频系统是否已初始化
   * @returns 是否已初始化
   */
  isReady(): boolean {
    return this.isInitialized && this.audioManager.isReady();
  }

  /**
   * 检查背景音乐是否正在播放
   * @returns 是否正在播放背景音乐
   */
  isMusicPlaying(): boolean {
    return this.audioManager.isMusicPlaying();
  }

  /**
   * 获取所有可用的音频主题
   * @returns 音频主题配置数组
   */
  getAvailableThemes(): AudioThemeConfig[] {
    return Object.values(AUDIO_THEMES);
  }

  /**
   * 预加载指定主题的所有音频资源
   * @param themeName - 主题名称
   * @returns Promise<void>
   */
  async preloadTheme(themeName: string): Promise<void> {
    const themeConfig = getAudioThemeConfig(themeName);
    if (!themeConfig) {
      throw new Error(`未找到音频主题: ${themeName}`);
    }

    try {
      // 预加载背景音乐
      await this.loadBackgroundMusic(themeConfig.backgroundMusic);

      // 预加载主题相关的音效
      if (themeConfig.soundOverrides) {
        const soundLoadPromises = Object.keys(themeConfig.soundOverrides).map(soundType =>
          this.loadSoundEffect(soundType as SoundEffectType)
        );
        await Promise.all(soundLoadPromises);
      }

      console.log(`主题 ${themeName} 的音频资源预加载完成`);
    } catch (error) {
      console.error(`预加载主题 ${themeName} 失败:`, error);
      throw error;
    }
  }

  /**
   * 销毁游戏音频系统
   * 清理所有资源和状态
   * @example
   * gameAudioSystem.destroy();
   */
  destroy(): void {
    this.stopBackgroundMusic();
    this.audioManager.destroy();
    this.loadingPromises.clear();
    this.currentTheme = 'gameNormal';
    this.currentBackgroundMusic = null;
    this.isInitialized = false;
    console.log('游戏音频系统已销毁');
  }
}

/**
 * 游戏音频系统单例实例
 * 全局唯一的游戏音频系统实例
 * @example
 * import { gameAudioSystem } from '@/game/GameAudioSystem';
 * await gameAudioSystem.initialize();
 */
export const gameAudioSystem = new GameAudioSystem(new AudioManager());